package vmo;


import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.FloatBuffer;
import java.util.EventListener;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.util.vector.Matrix4f;

import client.MainScene;

import server.Server;
import shared.Button;
import shared.LogWindow;
import shared.MouseHook;
import shared.MyListener;
import shared.NuFont;
import shared.Scene;
import shared.Textwindow;
import shared.Tools;
import shared.Vec2f;
import shared.Vec2i;
import shared.Window;
import network.Client;
import network.Packet;
import network.Packet_Message;
import network.Packet_Player;

public class Lobby implements Scene, MyListener
{

	Client m_client=null;
	
	
	
	Window m_window;
	
	
	//Button[] m_buttons;
	//for the two buttons
	int [] m_variables;
	int [] m_textureIDs;
	FloatBuffer matrix44Buffer;
	Matrix4f m_viewmatrix;
	LogWindow m_log;
	
	Window m_subwindow;
	Textwindow[] m_text;
	//NuFont m_font;
	
	public Lobby(int [] variables)
	{
		
		GL11.glClearColor(0.4f, 0.6f, 0.9f, 0f);		
		
		m_variables=variables;
		m_textureIDs=new int[4];
		m_textureIDs[0]=Tools.loadPNGTexture("assets/art/window.png", GL13.GL_TEXTURE0);
		m_textureIDs[1]=Tools.loadPNGTexture("assets/art/button.png", GL13.GL_TEXTURE0);		
		m_textureIDs[2]=Tools.loadPNGTexture("assets/art/font.png", GL13.GL_TEXTURE0);		
		m_textureIDs[3]=Tools.loadPNGTexture("assets/art/grey.png", GL13.GL_TEXTURE0);		
		//m_buttons=new Button[2];
		m_window=new Window(new Vec2f(-12,-6.5F),new Vec2f(24,16),m_textureIDs[0],true);

		m_viewmatrix=new Matrix4f();
		m_viewmatrix.m00=0.08F;
		m_viewmatrix.m11=0.1F;
		m_viewmatrix.m22=1.0F;
		m_viewmatrix.m33=1.0F;	
		
		Button [] buttons=new Button[3];
		
		//setup server button
		buttons[0]=new Button(new Vec2f(0.5F,0.5F), new Vec2f(4,2), m_textureIDs,1, this, "Server", 0);
		//setup client button
		buttons[1]=new Button(new Vec2f(5.0F,0.5F), new Vec2f(4,2), m_textureIDs,1, this, "Client", 1);		
		//setup log window
		buttons[2]=new Button(new Vec2f(18.5F,0.5F), new Vec2f(5,2), m_textureIDs,1, this, "Connect", 2);	
		m_log=new LogWindow(new Vec2f(0.5F,3), m_textureIDs[2],24,48);
		
		m_window.Add(m_log);
		m_window.Add(buttons[0]);
		m_window.Add(buttons[1]);
		
		matrix44Buffer=BufferUtils.createFloatBuffer(16);		
		
	//	m_font=new NuFont(new Vec2f(0,0), m_textureIDs[2], 128);
	//	m_font.setString("test string");
		
		m_subwindow=new Window(new Vec2f(-12,-9.5F),new Vec2f(24,3),m_textureIDs[0],false);
		m_subwindow.Add(buttons[2]);
		int []b={m_textureIDs[2],m_textureIDs[3]};
		m_text=new Textwindow[2];
		m_text[0]=new Textwindow(b, new Vec2f(0.5F,1.0F), new Vec2f(10,1), m_variables[0],"IP Address");
		m_subwindow.Add(m_text[0]);
		m_text[1]=new Textwindow(b, new Vec2f(11.0F,1.0F), new Vec2f(7,1), m_variables[0],"Handle");	
		m_subwindow.Add(m_text[1]);
	}
	
	@Override
	public void Update(float dt) {
		// TODO Auto-generated method stub
		//if either server or client are non null process their messages from here to generate log messages
		m_window.Update();
		m_subwindow.Update();
		
		if (m_client!=null)
		{
			m_client.Update(dt);
			ReadClient();
		}
	}

	@Override
	public void Draw() {
		// TODO Auto-generated method stub
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

		//need to set use shader here
		//GL20.glUseProgram(m_pshader);
		GL13.glActiveTexture(GL13.GL_TEXTURE0);
		
		//set tint to default
		GL20.glUniform4f(m_variables[0],1.0F,1.0F,1.0F, 1);
		
		//set standard viewing matrix
		m_viewmatrix.store(matrix44Buffer); matrix44Buffer.flip();
		GL20.glUniformMatrix4(m_variables[1], false, matrix44Buffer);	
		m_window.Draw(matrix44Buffer, m_variables[2]);
		m_subwindow.Draw(matrix44Buffer, m_variables[2]);
	//	m_font.Draw(matrix44Buffer, m_variables[2]);
		
	}

	@Override
	public void Start(MouseHook mouse) {
		// TODO Auto-generated method stub
		//hook the window into the mouse handler
		mouse.Register(m_window);
		mouse.Register(m_subwindow);
	}

	@Override
	public void End() {
		// TODO Auto-generated method stub
		m_window.Discard();
		m_subwindow.Discard();
	//	m_font.Discard();

		if (m_client!=null)
		{
			m_client.Discard();
		}
	}

	@Override
	public void ButtonCallback(int ID, Vec2f p) {
		// TODO Auto-generated method stub
		//figure out which button got clicked 
		switch (ID)
		{
		case 0:
			//start server
			if (Game.g_server==null)
			{
				Game.g_server=new Server();
				Game.g_serverthread=new Thread(Game.g_server);
				Game.g_serverthread.start();
				m_log.AddString("server initialized", m_textureIDs[2]);
			}
			break;
			
		case 1:
			m_subwindow.setActive(true);
			break;
		case 2:
			//start client
			if (m_client==null)
			{
				m_client=new Client();
				m_log.AddString("client initialized", m_textureIDs[2]);		
				try {
					m_client.Connect(InetAddress.getByName(m_text[0].m_string),m_text[1].m_string,null);
				} catch (UnknownHostException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		
			break;
		
		}
		//start the server or client appropriately
	}

	public void ReadClient()
	{
		Packet p=m_client.getPacket();
		if (p!=null)
		{
			String str="client ";
			//read packet, especially if it's a handshake
			switch (p.getType())
			{
				case MESSAGE:
				Packet_Message pa=(Packet_Message) p;
				switch (pa.m_msgtype)
				{
				case ACKNOWLEDGEMENT:
					str=str+"server welcome message: "+pa.m_string;							
					break;
				
				}
		
				m_log.AddString(str, m_textureIDs[2]);				
				break;
				
				case PLAYER:
				str=str+" ping received timestamp "+p.getTimestamp();
				m_log.AddString(str, m_textureIDs[2]);	
				//transition to next scene
				Client ci=m_client; m_client=null;
				Game.g_manager.SwapScene(new MainScene(ci,m_variables,(Packet_Player)p));			
				break;
				
				case ALIVE:
					str=str+" keep alive received timestamp "+p.getTimestamp();
					m_log.AddString(str, m_textureIDs[2]);						
				break;
			
			}
		}
	}	
}
